package com.ecloud.common.web.result;

import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import com.ecloud.common.base.result.Result;
import com.ecloud.common.base.result.ResultBuilder;
import com.ecloud.common.base.result.ResultStatus;

import feign.RetryableException;

/**
 * 断路器结果构造器
 *
 * @author LiuGangQiang Create in 2021/08/09
 */
public final class FallBackBuilder {

    /**
     * 隐藏构造器
     *
     * @author LiuGangQiang Create in 2021/08/15
     */
    private FallBackBuilder() {
    }

    /**
     * 根据异常构造结果
     *
     * @author LiuGangQiang Create in 2021/08/15
     * @param cause 异常
     * @return {@link Result}
     */
    public static <T> Result<T> build(Throwable throwable) {
        if (throwable instanceof FlowException) {
            /* 接口限流异常 */
            return ResultBuilder.build(ResultStatus.TOO_MANY_REQUESTS);
        } else if (throwable instanceof ParamFlowException) {
            /* 热点限流异常 */
            return ResultBuilder.build(ResultStatus.HOT_PARAM_FLOW);
        } else if (throwable instanceof DegradeException) {
            /* 服务降级异常 */
            return ResultBuilder.build(ResultStatus.SERVICE_DEGRADE);
        } else if (throwable instanceof SystemBlockException) {
            /* 系统保护异常 */
            return ResultBuilder.build(ResultStatus.SYSTEM_BLOCK);
        } else if (throwable instanceof AuthorityException) {
            /* 授权规则异常 */
            return ResultBuilder.build(ResultStatus.AUTHORITY);
        } else if (throwable instanceof RetryableException) {
            /* 连接超时异常 */
            return ResultBuilder.build(ResultStatus.TIMEOUT);
        } else {
            /* 其他未知异常 */
            return ResultBuilder.build(ResultStatus.SYSTEM_ERROR);
        }
    }
}
